package cn.ztuo.bitrade.service;

import cn.ztuo.bitrade.Trade.CoinTrader;
import cn.ztuo.bitrade.Trade.CoinTraderFactory;
import cn.ztuo.bitrade.entity.ContractCoin;
import cn.ztuo.bitrade.entity.ContractOrder;
import cn.ztuo.bitrade.entity.ContractOrderDirection;
import cn.ztuo.bitrade.runnable.RobotOrderRunnable;
import cn.ztuo.bitrade.util.ContractUtils;
import cn.ztuo.bitrade.util.MessageResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

@Slf4j
@Service
public class ContractService {
    @Autowired
    private CoinTraderFactory traderFactory;
    @Autowired
    private KafkaTemplate<String, String> kafkaTemplate;
    @Autowired
    private ContractOrderService contractOrderService;

    //机器人下订
    public static final ExecutorService executor = Executors.newCachedThreadPool();

    public MessageResult robotAddOrder(String symbol) {
        List<ContractCoin> coins = ContractUtils.findBaseSymbols();
        Map<String, Map<ContractOrderDirection, List<ContractOrder>>> plateMap = RobotOrderRunnable.plateMap;
        if (StringUtils.isBlank(symbol)) {
            coins.stream().forEach(coin -> {
                CoinTrader coinTrader = traderFactory.getTrader(symbol);
                Map<ContractOrderDirection, List<ContractOrder>> mapPlate = new HashMap<>();
                if (!plateMap.isEmpty() && plateMap.containsKey(coin.getSymbol()) && plateMap.get(coin.getSymbol()) != null) {
                    mapPlate = plateMap.get(coin.getSymbol());
                    List<ContractOrder> bidsOld = mapPlate.get(ContractOrderDirection.BUY);
                    List<ContractOrder> asksOld = mapPlate.get(ContractOrderDirection.SELL);
                    coinTrader.cancelRobotOrder(bidsOld, ContractOrderDirection.BUY);
                    coinTrader.cancelRobotOrder(asksOld, ContractOrderDirection.SELL);
                }
                RobotOrderRunnable robotOrderRunnable = new RobotOrderRunnable( contractOrderService, coin,coinTrader,this);
                executor.execute(robotOrderRunnable);
            });
        } else {
            CoinTrader coinTrader = traderFactory.getTrader(symbol);
            ContractCoin coin = coins.stream().filter(a -> a.getSymbol().equals(symbol)).findAny().get();
            Map<ContractOrderDirection, List<ContractOrder>> mapPlate = new HashMap<>();
            if (!plateMap.isEmpty() && plateMap.containsKey(coin.getSymbol()) && plateMap.get(coin.getSymbol()) != null) {
                mapPlate = plateMap.get(coin.getSymbol());
                List<ContractOrder> bidsOld = mapPlate.get(ContractOrderDirection.BUY);
                List<ContractOrder> asksOld = mapPlate.get(ContractOrderDirection.SELL);
                coinTrader.cancelRobotOrder(bidsOld, ContractOrderDirection.BUY);
                coinTrader.cancelRobotOrder(asksOld, ContractOrderDirection.SELL);
            }
            RobotOrderRunnable robotOrderRunnable = new RobotOrderRunnable( contractOrderService, coin,coinTrader,this);
            executor.execute(robotOrderRunnable);
        }
        return MessageResult.success(symbol+"当前机器人----------------------");
    }

    public MessageResult robotAddOrder(ContractCoin coin) {
        synchronized (coin) {
            CoinTrader coinTrader = traderFactory.getTrader(coin.getSymbol());
            RobotOrderRunnable robotOrderRunnable = new RobotOrderRunnable( contractOrderService, coin,coinTrader,this);
            executor.execute(robotOrderRunnable);
        }
        return MessageResult.success(coin.getSymbol() + "当前机器人-------------------------------");
    }
}
